#pragma GCC optimize(2)
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <map>
#include <vector>

using namespace std;
using LL = long long;
const int N = 110;
const int mod = 998244353;

int n;
LL a[N][N], f[N][N];

/*
Suppose we build the string from left to right, and when we place the i-th character, we ensure that all substrings ending with the i-th character are valid. What do we need to know in order to calculate the number of different characters in the string ending with the i-th character?

Suppose the character si is 0. Let's try going to the left of it. The string from i to i will have the same characters; but if there is at least one character 1 before the i-th position, the string s1s2s3…si will have two different characters. What about the strings in the middle? The string sjsj+1…si will contain different characters if and only if there is at least one 1 in [j,i) (since si is 0), so we are actually interested in the position of the last character 1 before i.

The same logic applies if the character si is 1: we are only interested in the position of the last 0 before i, and it is enough to check if all substrings ending with the i-th character are violated.

What if when we choose the i-th character, we violate some substring that doesn't end in the i-th position? Well, you could also check that... or you could just ignore it. Actually, it doesn't matter if this happens because it means that the substring that is violated ends in some position k>i; and we will check it when placing the k-th character.

So, the solution can be formulated with the following dynamic programming: let dpi,j be the number of ways to choose the first i characters of the string so that the last character different from si was sj (or j=0 if there was no such character), and all the constraints on the substrings ending no later than position i are satisfied. The transitions are simple: you either place the same character as the last one (going from dpi,j to dpi+1,j), or a different character (going from dpi,j to dpi+1,i); and when you place a character, you check all the constraints on the substrings ending with the i-th position. Note that the state dp1,0 is actually represented by two strings: 0 and 1.

This solution works in O(n3), although O(n4) or O(n2) implementations are also possible. 


*/

int main(){
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n;
    for(int i = 1; i <= n; i ++){
        for(int j = i; j <= n; j ++){
            cin >> a[i][j];
        }
    }

    f[1][1] = 2;
    for(int i = 1; i <= n; i ++){
        for(int j = 1; j <= i; j ++){
            bool flag = false;
            for(int k = 1; k <= i; k ++){
                if(a[k][i] == 1 && k < j) flag = true;
                if(a[k][i] == 2 && k >= j) flag = true;
            }

            if(flag) f[i][j] = 0;
            f[i + 1][j] = (f[i + 1][j] + f[i][j]) % mod;
            f[i + 1][i + 1] = (f[i + 1][i + 1] + f[i][j]) % mod;
        }
    }

    LL res = 0;
    for(int i = 1; i <= n; i ++){
        res = (res + f[n][i]) % mod; 
    }

    cout <<  res << '\n';


    return 0;
}